package com.haibo.test.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.haibo.test.constant.PublicConstant;
import com.haibo.test.model.domain.Clinic;
import com.haibo.test.model.domain.WorkTime;
import com.haibo.test.service.KillService;
import com.haibo.test.utils.DateUtil;
import com.haibo.test.utils.HttpClientUtils;
import com.haibo.test.utils.MD5Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Classname RemainingService <br>
 * @Description TODO <br>
 * @Date 2020-4-29 13:44 <br>
 * @Created by mxw<br>
 */
@Slf4j
@Service
public class RemainingService implements KillService {

  private HttpClientUtils httpClientUtil = new HttpClientUtils();
  // 九价疫苗
  private static Integer vaccineCode = 8803;
  // 获取可以预约列表
  private static String listUrl =
      "https://wx.healthych.com/base/department/getHpvDepartments.do?vaccineCode=8803&latitude=30.599261&longitude=103.5436";

  // 查询哪天可以预约
  private static String dayList = "https://wx.healthych.com/order/subscribe/workDays.do?";
  // 获取可以预约的数量
  private static String subUrl =
      "https://wx.healthych.com/order/subscribe/findSubscribeAmountByDays.do?";
  // 查询可以预约的时间段
  private String departmentWorkTimes =
      "https://wx.healthych.com/order/subscribe/departmentWorkTimes2.do?";
  // 下单
  private String orderUrl = "https://wx.healthych.com/order/subscribe/add.do?";
  // 查询
  private String queryUrl = "https://wx.healthych.com/order/subscribe/clientDetail.do?id=";

  // 推消息
  private static String pushUrl =
      "https://sc.ftqq.com/"+PublicConstant.pushId+".send?";

  @Override
  @Scheduled(cron = "0 */1 * * * ?")
  //  @Scheduled(fixedRate = 100)
  public void Kill1() throws Exception {

    String result = httpClientUtil.sendGet(listUrl, null);
    JSONObject jsStr = JSONObject.parseObject(result);

    if (null == result || !StringUtils.equals("0000", jsStr.getString("code"))) {
      log.info(jsStr.toJSONString());
      return;
    }

    JSONArray rows = jsStr.getJSONObject("data").getJSONArray("rows");
    List<Clinic> clinics = JSONObject.parseArray(rows.toJSONString(), Clinic.class);
    log.info("检漏列表：");
    clinics
        .parallelStream()
        .forEach(
            clinic -> {
              String format =
                  String.format(
                      "代码：%-6s名字:%-15s地址:%-24s电话：%-12s",
                      clinic.getDepaVaccId(),
                      clinic.getName(),
                      clinic.getAddress(),
                      clinic.getTel());
              log.info(
                  "代码：{} 名字:{} 地址:{} 电话：{}",
                  clinic.getDepaVaccId(),
                  clinic.getName(),
                  clinic.getAddress(),
                  clinic.getTel());
              //               筛选条件
              if (format.indexOf("成都") >= 0
                  || format.indexOf("彭州") >= 0
                  || format.indexOf("郫都") >= 0
                  || format.indexOf("大邑") >= 0
                  || format.indexOf("龙泉驿") >= 0
                  || format.indexOf("金牛") >= 0) {

                // 如果是开放预约的
                if (clinic.getIsOpen() == 1) {
                  // 推送消息
                  String s = pushMsg("发现新的疫苗", format);
                  // 找出可以预约的日期
                  JSONObject day = getDay(clinic);
                  if (day != null) {
                    JSONArray dateList = day.getJSONObject("data").getJSONArray("dateList");
                    List<String> dateLists =
                        JSONObject.parseArray(dateList.toJSONString(), String.class);

                    //                    // 找出当前可以预约的最大数量
                    //                    // 获取剩余数量
                    //                    JSONObject maxSub1 = getMaxSub(clinic, dateLists);
                    //
                    //                    JSONArray data = maxSub1.getJSONArray("data");
                    //
                    //                    Iterator<Object> iterator = data.iterator();
                    //                    iterator.forEachRemaining(
                    //                        next -> {
                    //                          JSONObject jsonObject = (JSONObject) next;
                    //                          int maxSub = jsonObject.getIntValue("maxSub");
                    //                          String dayStr = jsonObject.getString("day");
                    // 如果还剩的有有可以约的
                    //                          if (maxSub > 0) {
                    //                            log.info("可以预约的日期：" + next);
                    dateLists
                        .parallelStream()
                        .forEach(
                            dayStr -> {
                              // 查询可以预约的时间段
                              JSONObject workTimesJson = getDepartmentWorkTimes(clinic, dayStr);
                              log.info("可以预约的时间：" + workTimesJson);
                              JSONArray jsonArray =
                                  workTimesJson
                                      .getJSONObject("data")
                                      .getJSONObject("times")
                                      .getJSONArray("data");
                              List<WorkTime> timeLists =
                                  JSONObject.parseArray(jsonArray.toJSONString(), WorkTime.class);
                              timeLists
                                  .parallelStream()
                                  .forEach(
                                      time -> {
                                        log.info("可以预约的时间：" + time);
                                        if (time.getMaxSub() > 0) {
                                          // 这个时间段还有剩的,就开始构造订单
                                          String now =
                                              workTimesJson.getJSONObject("data").getString("now");
                                          JSONObject orderJson =
                                              placeOrder(dayStr, clinic, time.getId(), now);
                                          if ("0000".equals(orderJson.getString("code"))) {
                                            // 如果预约成功的话，再查询预约结果
                                            String subscribeId =
                                                orderJson
                                                    .getJSONObject("data")
                                                    .getString("subscribeId");
                                            // 查询预约结果
                                            JSONObject query = query(subscribeId);
                                            pushMsg("程序自动预约结果", query.toJSONString());
                                          }
                                        }
                                      });
                              //                          }
                            });
                  }
                }
              }
            });
  }

  /**
   * 下单
   *
   * @param date 日期
   * @param clinic 诊所对象 @Param subscirbeTime 时间
   * @return
   * @throws Exception
   */
  public JSONObject placeOrder(String date, Clinic clinic, int subscirbeTime, String now) {

    Map<String, Object> orderParams = new HashMap<>();
    orderParams.put("vaccineCode", vaccineCode);
    orderParams.put("vaccineIndex", 1);
    orderParams.put("linkmanId", PublicConstant.linkmanId);
    orderParams.put("subscribeDate", date);
    orderParams.put("subscirbeTime", subscirbeTime);
    orderParams.put("departmentVaccineId", clinic.getDepaVaccId());

    orderParams.put(
        "depaCode",
        clinic.getCode()
            + "_"
            + MD5Utils.MD5Encode(
                DateUtil.strToDateFormat(now, "YYYYMMddHHmm") + subscirbeTime + "fuckhacker10000",
                "utf8"));

    orderParams.put("serviceFee", 0);
    log.info("**********************预约信息**********************");
    log.info(
        "疫苗代码：{} 预约日期：{} 时间代码：{} 医院代码：{} 医院名称:{} 套餐代码：{} 时间:{} ",
        vaccineCode,
        date,
        subscirbeTime,
        clinic.getCode(),
        clinic.getName(),
        clinic.getDepaVaccId(),
        DateUtil.strToDateFormat(now, "YYYYMMddHHmm"));
    log.info("***************************************************");

    String orderStr = null;
    try {
      orderStr = httpClientUtil.sendGet(orderUrl, orderParams);

      log.info("下订单：");
      log.info(orderStr);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return JSONObject.parseObject(orderStr);
  }

  /**
   * 查询结果
   *
   * @param subscribeId 订单号
   * @return
   */
  public JSONObject query(String subscribeId) {

    try {
      String result = httpClientUtil.sendGet(queryUrl + subscribeId, null);
      log.info("预约结果：" + result);
      return JSONObject.parseObject(result);
    } catch (Exception e) {
      e.printStackTrace();
    }

    return null;
  }

  @Deprecated
  public JSONObject getMaxSub(Clinic clinic, List<String> dateLists) {
    for (int i = 0; i < 10; i++) {
      Map<String, Object> subParams = new HashMap<>();
      subParams.put("depaCode", clinic.getCode());
      subParams.put("vaccCode", vaccineCode);
      subParams.put("vaccIndex", 1);
      subParams.put("days", String.join(",", dateLists));
      subParams.put("departmentVaccineId", clinic.getDepaVaccId());
      try {
        String subData = httpClientUtil.sendGet(subUrl, subParams);
        log.info("getMaxSub：");
        log.info(subData);
        return JSONObject.parseObject(subData);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return null;
  }

  /** 查询可以预约的时间段 */
  public JSONObject getDepartmentWorkTimes(Clinic clinic, String date) {
    while (true) {
      Map<String, Object> timeParams = new HashMap<>();
      timeParams.put("depaCode", clinic.getCode());
      timeParams.put("vaccCode", vaccineCode);
      timeParams.put("vaccIndex", 1);
      timeParams.put("subsribeDate", date);
      timeParams.put("departmentVaccineId", clinic.getDepaVaccId());
      timeParams.put("linkmanId", PublicConstant.linkmanId);

      try {
        String workTimes = httpClientUtil.sendGet(departmentWorkTimes, timeParams);
        if (workTimes != null) {
          JSONObject workTimesJson = JSONObject.parseObject(workTimes);
          log.info("getDepartmentWorkTimes：");
          log.info(workTimes);

          return workTimesJson;
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  // 获取可以预约的日期
  public JSONObject getDay(Clinic clinic) {
    while (true) {
      Map<String, Object> params = new HashMap<>();
      params.put("depaCode", clinic.getCode());
      params.put("linkmanId", PublicConstant.linkmanId);
      params.put("vaccCode", vaccineCode);
      params.put("vaccIndex", 1);
      params.put("departmentVaccineId", clinic.getDepaVaccId());
      try {
        String day = httpClientUtil.sendGet(dayList, params);
        log.info("获取可以预约的日期：");
        log.info(day);
        if (day != null) {
          JSONObject jsonObject = JSONObject.parseObject(day);
          return jsonObject;
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  /**
   * 推送消息
   *
   * @param title
   * @return
   */
  public String pushMsg(String title, String desp) {

    Map<String, Object> push = new HashMap<>();
    push.put("text", URLEncoder.encode(title));
    push.put("desp", URLEncoder.encode(desp));
    String ss = null;
    try {
      ss = httpClientUtil.sendGet(pushUrl, push);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return ss;
  }
}
